import zipfile
import datetime
import multiprocessing
from multiprocessing.pool import ThreadPool
from tqdm import tqdm
import json
import time
import os
# import os.path
import sys




china_tiles = {
    "浙江省": [
        "50RQV",
        "50RPU",
        "50RQU",
        "50RNT",
        "50RPT",
        "50RQT",
        "50RPS",
        "50RQS",
        "50RPR",
        "50RQR",
        "51RTQ",
        "51RUQ",
        "51RTP",
        "51RUP",
        "51RVP",
        "51RTN",
        "51RUN",
        "51RVN",
        "51RTM",
        "51RUM",
        "51RTL",
        "51RUL"
    ],
    "云南省": [
        "48QTM",
        "48QUM",
        "48QVM",
        "48QWM",
        "48QXM",
        "48QTL",
        "48QUL",
        "48QVL",
        "48QWL",
        "48QXL",
        "48QTK",
        "48QUK",
        "48RUS",
        "48RVS",
        "48RWS",
        "48RTR",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RTQ",
        "48RUQ",
        "48RVQ",
        "48RTP",
        "48RUP",
        "48RVP",
        "48RTN",
        "48RUN",
        "48RVN",
        "48RWN",
        "47QLG",
        "47QMG",
        "47QNG",
        "47QPG",
        "47QQG",
        "47QRG",
        "47QMF",
        "47QNF",
        "47QPF",
        "47QQF",
        "47QRF",
        "47QNE",
        "47QPE",
        "47QQE",
        "47QRE",
        "47QPD",
        "47QQD",
        "47RMN",
        "47RNN",
        "47RMM",
        "47RNM",
        "47RPM",
        "47RML",
        "47RNL",
        "47RPL",
        "47RQL",
        "47RMK",
        "47RNK",
        "47RPK",
        "47RQK",
        "47RMJ",
        "47RNJ",
        "47RPJ",
        "47RQJ",
        "47RRJ",
        "47RLH",
        "47RMH",
        "47RNH",
        "47RPH",
        "47RQH",
        "47RRH"
    ],
    "新疆": [
        "43SCD",
        "43SDD",
        "43SED",
        "43SFD",
        "43SGD",
        "43SCC",
        "43SDC",
        "43SEC",
        "43SFC",
        "43SGC",
        "43SDB",
        "43SEB",
        "43SFB",
        "43SGB",
        "43SDA",
        "43SEA",
        "43SFA",
        "43SGA",
        "43SEV",
        "43SFV",
        "43SGV",
        "43TEF",
        "43TFF",
        "43TGF",
        "43TDE",
        "43TEE",
        "43TFE",
        "43TGE",
        "44SKJ",
        "44SLJ",
        "44SMJ",
        "44SNJ",
        "44SPJ",
        "44SQJ",
        "44SKH",
        "44SLH",
        "44SMH",
        "44SNH",
        "44SPH",
        "44SQH",
        "44SKG",
        "44SLG",
        "44SMG",
        "44SNG",
        "44SPG",
        "44SQG",
        "44SKF",
        "44SLF",
        "44SMF",
        "44SNF",
        "44SPF",
        "44SQF",
        "44SKE",
        "44SLE",
        "44SME",
        "44SNE",
        "44SPE",
        "44SQE",
        "44SKD",
        "44SLD",
        "44SMD",
        "44SND",
        "44TPT",
        "44TQT",
        "44TPS",
        "44TQS",
        "44TMR",
        "44TNR",
        "44TPR",
        "44TQR",
        "44TMQ",
        "44TNQ",
        "44TPQ",
        "44TQQ",
        "44TMP",
        "44TNP",
        "44TPP",
        "44TQP",
        "44TMN",
        "44TNN",
        "44TPN",
        "44TQN",
        "44TLM",
        "44TMM",
        "44TNM",
        "44TPM",
        "44TQM",
        "44TKL",
        "44TLL",
        "44TML",
        "44TNL",
        "44TPL",
        "44TQL",
        "44TKK",
        "44TLK",
        "44TMK",
        "44TNK",
        "44TPK",
        "44TQK",
        "45STD",
        "45SUD",
        "45SVD",
        "45SWD",
        "45SXD",
        "45SYD",
        "45STC",
        "45SUC",
        "45SVC",
        "45SWC",
        "45SXC",
        "45SYC",
        "45STB",
        "45SUB",
        "45SVB",
        "45SWB",
        "45SXB",
        "45SYB",
        "45STA",
        "45SUA",
        "45SVA",
        "45SWA",
        "45SXA",
        "45SYA",
        "45STV",
        "45SUV",
        "45SVV",
        "45SYV",
        "45TUN",
        "45TVN",
        "45TWN",
        "45TXN",
        "45TYN",
        "45TUM",
        "45TVM",
        "45TWM",
        "45TXM",
        "45TYM",
        "45TUL",
        "45TVL",
        "45TWL",
        "45TXL",
        "45TYL",
        "45TUK",
        "45TVK",
        "45TWK",
        "45TXK",
        "45TYK",
        "45TUJ",
        "45TVJ",
        "45TWJ",
        "45TXJ",
        "45TYJ",
        "45TUH",
        "45TVH",
        "45TWH",
        "45TXH",
        "45TYH",
        "45TUG",
        "45TVG",
        "45TWG",
        "45TXG",
        "45TYG",
        "45TTF",
        "45TUF",
        "45TVF",
        "45TWF",
        "45TXF",
        "45TYF",
        "45TTE",
        "45TUE",
        "45TVE",
        "45TWE",
        "45TXE",
        "45TYE",
        "45UVQ",
        "45UWQ",
        "45UUP",
        "45UVP",
        "45UWP",
        "45UXP",
        "46SBJ",
        "46SCJ",
        "46SDJ",
        "46SBH",
        "46SCH",
        "46SBG",
        "46SCG",
        "46SBF",
        "46SCF",
        "46SBE",
        "46SCE",
        "46TCT",
        "46TCS",
        "46TCR",
        "46TCQ",
        "46TDQ",
        "46TEQ",
        "46TFQ",
        "46TCP",
        "46TDP",
        "46TEP",
        "46TFP",
        "46TGP",
        "46TCN",
        "46TDN",
        "46TEN",
        "46TFN",
        "46TGN",
        "46TCM",
        "46TDM",
        "46TEM",
        "46TFM",
        "46TGM",
        "46TBL",
        "46TCL",
        "46TDL",
        "46TEL",
        "46TFL",
        "46TBK",
        "46TCK",
        "46TDK",
        "46TEK",
        "45TTG",
        "46TBM",
        "47TKG"
    ],
    "香港": [
        "49QGE",
        "49QHE",
        "50QKK"
    ],
    "西藏": [
        "44RKV",
        "44RLV",
        "44RMV",
        "44RNV",
        "44RPV",
        "44RQV",
        "44RMU",
        "44RNU",
        "44RPU",
        "44RQU",
        "44RPT",
        "44RQT",
        "44SME",
        "44SNE",
        "44SPE",
        "44SQE",
        "44SLD",
        "44SMD",
        "44SND",
        "44SPD",
        "44SQD",
        "44SKC",
        "44SLC",
        "44SMC",
        "44SNC",
        "44SPC",
        "44SQC",
        "44SKB",
        "44SLB",
        "44SMB",
        "44SNB",
        "44SPB",
        "44SQB",
        "44SKA",
        "44SLA",
        "44SMA",
        "44SNA",
        "44SPA",
        "44SQA",
        "45RTQ",
        "45RUQ",
        "45RVQ",
        "45RWQ",
        "45RXQ",
        "45RYQ",
        "45RTP",
        "45RUP",
        "45RVP",
        "45RWP",
        "45RXP",
        "45RYP",
        "45RTN",
        "45RUN",
        "45RVN",
        "45RWN",
        "45RXN",
        "45RYN",
        "45RTM",
        "45RUM",
        "45RVM",
        "45RWM",
        "45RXM",
        "45RYM",
        "45RUL",
        "45RVL",
        "45RWL",
        "45RXL",
        "45RYL",
        "45SVA",
        "45SWA",
        "45SXA",
        "45SYA",
        "45STV",
        "45SUV",
        "45SVV",
        "45SWV",
        "45SXV",
        "45SYV",
        "45STU",
        "45SUU",
        "45SVU",
        "45SWU",
        "45SXU",
        "45SYU",
        "45STT",
        "45SUT",
        "45SVT",
        "45SWT",
        "45SXT",
        "45SYT",
        "45STS",
        "45SUS",
        "45SVS",
        "45SWS",
        "45SXS",
        "45SYS",
        "45STR",
        "45SUR",
        "45SVR",
        "45SWR",
        "45SXR",
        "45SYR",
        "46RBV",
        "46RCV",
        "46RDV",
        "46REV",
        "46RFV",
        "46RGV",
        "46RBU",
        "46RCU",
        "46RDU",
        "46REU",
        "46RFU",
        "46RGU",
        "46RBT",
        "46RCT",
        "46RDT",
        "46RET",
        "46RFT",
        "46RGT",
        "46RBS",
        "46RCS",
        "46RDS",
        "46RES",
        "46RFS",
        "46RGS",
        "46RBR",
        "46RCR",
        "46RDR",
        "46RER",
        "46RFR",
        "46RGR",
        "46RDQ",
        "46REQ",
        "46SBC",
        "46SBB",
        "46SCB",
        "46SDB",
        "46SEB",
        "46SFB",
        "46SBA",
        "46SCA",
        "46SDA",
        "46SEA",
        "46SFA",
        "46SGA",
        "47RKQ",
        "47RLQ",
        "47RMQ",
        "47RKP",
        "47RLP",
        "47RMP",
        "47RNP",
        "47RKN",
        "47RLN",
        "47RMN",
        "47RNN",
        "47RKM",
        "47RLM",
        "47RMM",
        "47RKL",
        "47RLL",
        "47SLS",
        "47SKR",
        "47SLR",
        "47SMR"
    ],
    "台湾省": [
        "51QTG",
        "51QUG",
        "51QTF",
        "51QUF",
        "51QTE",
        "51RTH",
        "51RUH"
    ],
    "四川省": [
        "48RTV",
        "48RUV",
        "48RVV",
        "48RWV",
        "48RXV",
        "48RYV",
        "48RTU",
        "48RUU",
        "48RVU",
        "48RWU",
        "48RXU",
        "48RYU",
        "48RTT",
        "48RUT",
        "48RVT",
        "48RWT",
        "48RXT",
        "48RTS",
        "48RUS",
        "48RVS",
        "48RWS",
        "48RXS",
        "48RTR",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RXR",
        "48RTQ",
        "48RUQ",
        "48RTP",
        "48STC",
        "48SUC",
        "48SVC",
        "48STB",
        "48SUB",
        "48SVB",
        "48SWB",
        "48SXB",
        "48SYB",
        "48STA",
        "48SUA",
        "48SVA",
        "48SWA",
        "48SXA",
        "48SYA",
        "49RBQ",
        "49SBR",
        "47RMQ",
        "47RNQ",
        "47RPQ",
        "47RQQ",
        "47RMP",
        "47RNP",
        "47RPP",
        "47RQP",
        "47RMN",
        "47RNN",
        "47RPN",
        "47RQN",
        "47RNM",
        "47RPM",
        "47RQM",
        "47RPL",
        "47RQL",
        "47RQK",
        "47RQJ",
        "47RRJ",
        "47SLT",
        "47SMT",
        "47SQT",
        "47SLS",
        "47SMS",
        "47SNS",
        "47SPS",
        "47SQS",
        "47SLR",
        "47SMR",
        "47SNR",
        "47SPR",
        "47SQR"
    ],
    "陕西省": [
        "48SXG",
        "48SYG",
        "48SYF",
        "48SYE",
        "48SXD",
        "48SYD",
        "48SWC",
        "48SXC",
        "48SYC",
        "48SWB",
        "48SXB",
        "48SYB",
        "48SXA",
        "48SYA",
        "49SCD",
        "49SDD",
        "49SED",
        "49SCC",
        "49SDC",
        "49SEC",
        "49SBB",
        "49SCB",
        "49SDB",
        "49SBA",
        "49SCA",
        "49SDA",
        "49SBV",
        "49SCV",
        "49SDV",
        "49SBU",
        "49SCU",
        "49SDU",
        "49SBT",
        "49SCT",
        "49SDT",
        "49SET",
        "49SBS",
        "49SCS",
        "49SDS",
        "49SES",
        "49SBR",
        "49SCR"
    ],
    "山西省": [
        "49SDD",
        "49SED",
        "49SFD",
        "49SGD",
        "49SDC",
        "49SEC",
        "49SFC",
        "49SGC",
        "49SDB",
        "49SEB",
        "49SFB",
        "49SGB",
        "49SDA",
        "49SEA",
        "49SFA",
        "49SGA",
        "49SDV",
        "49SEV",
        "49SFV",
        "49SGV",
        "49SDU",
        "49SEU",
        "49SFU",
        "49TEE",
        "49TFE",
        "49TGE",
        "50SKJ",
        "50SKG",
        "50TKL",
        "50TKK"
    ],
    "山东省": [
        "50SNH",
        "50SPH",
        "50SLG",
        "50SMG",
        "50SNG",
        "50SPG",
        "50SQG",
        "50SLF",
        "50SMF",
        "50SNF",
        "50SPF",
        "50SQF",
        "50SLE",
        "50SME",
        "50SNE",
        "50SPE",
        "50SQE",
        "50SKD",
        "50SLD",
        "50SMD",
        "50SND",
        "50SPD",
        "50SQD",
        "51STB",
        "51SUB",
        "51SVB",
        "51STA",
        "51SUA",
        "51SVA",
        "51STV"
    ],
    "青海省": [
        "48STG",
        "48STF",
        "48SUF",
        "48STE",
        "48SUE",
        "48STD",
        "48STC",
        "45SYA",
        "45SYV",
        "45SYU",
        "45SYT",
        "46SCJ",
        "46SDJ",
        "46SEJ",
        "46SFJ",
        "46SGJ",
        "46SBH",
        "46SCH",
        "46SDH",
        "46SEH",
        "46SFH",
        "46SGH",
        "46SBG",
        "46SCG",
        "46SDG",
        "46SEG",
        "46SFG",
        "46SGG",
        "46SBF",
        "46SCF",
        "46SDF",
        "46SEF",
        "46SFF",
        "46SGF",
        "46SBE",
        "46SCE",
        "46SDE",
        "46SEE",
        "46SFE",
        "46SGE",
        "46SBD",
        "46SCD",
        "46SDD",
        "46SED",
        "46SFD",
        "46SGD",
        "46SBC",
        "46SCC",
        "46SDC",
        "46SEC",
        "46SFC",
        "46SGC",
        "46SBB",
        "46SCB",
        "46SDB",
        "46SEB",
        "46SFB",
        "46SGB",
        "46SEA",
        "46SFA",
        "46SGA",
        "47RKQ",
        "47SLD",
        "47SMD",
        "47SND",
        "47SKC",
        "47SLC",
        "47SMC",
        "47SNC",
        "47SPC",
        "47SKB",
        "47SLB",
        "47SMB",
        "47SNB",
        "47SPB",
        "47SQB",
        "47SKA",
        "47SLA",
        "47SMA",
        "47SNA",
        "47SPA",
        "47SQA",
        "47SKV",
        "47SLV",
        "47SMV",
        "47SNV",
        "47SPV",
        "47SQV",
        "47SKU",
        "47SLU",
        "47SMU",
        "47SNU",
        "47SPU",
        "47SQU",
        "47SKT",
        "47SLT",
        "47SMT",
        "47SNT",
        "47SPT",
        "47SQT",
        "47SKS",
        "47SLS",
        "47SMS",
        "47SNS",
        "47SPS",
        "47SQS",
        "47SKR",
        "47SLR",
        "47SPR"
    ],
    "宁夏": [
        "48SWJ",
        "48SXJ",
        "48SWH",
        "48SXH",
        "48SYH",
        "48SVG",
        "48SWG",
        "48SXG",
        "48SYG",
        "48SVF",
        "48SWF",
        "48SXF",
        "48SWE",
        "48SXE"
    ],
    "内蒙古": [
        "48STJ",
        "48SUJ",
        "48SVJ",
        "48SWJ",
        "48SXJ",
        "48SYJ",
        "48SUH",
        "48SVH",
        "48SWH",
        "48SXH",
        "48SYH",
        "48SUG",
        "48SVG",
        "48SWG",
        "48SYG",
        "48TXN",
        "48TYN",
        "48TUM",
        "48TVM",
        "48TWM",
        "48TXM",
        "48TYM",
        "48TTL",
        "48TUL",
        "48TVL",
        "48TWL",
        "48TXL",
        "48TYL",
        "48TTK",
        "48TUK",
        "48TVK",
        "48TWK",
        "48TXK",
        "48TYK",
        "49SBD",
        "49SCD",
        "49SDD",
        "49SED",
        "49SBC",
        "49SCC",
        "49SBB",
        "49SCB",
        "49TEK",
        "49TFK",
        "49TGK",
        "49TEJ",
        "49TFJ",
        "49TGJ",
        "49TCH",
        "49TDH",
        "49TEH",
        "49TFH",
        "49TGH",
        "49TCG",
        "49TDG",
        "49TEG",
        "49TFG",
        "49TGG",
        "49TBF",
        "49TCF",
        "49TDF",
        "49TEF",
        "49TFF",
        "49TGF",
        "49TBE",
        "49TCE",
        "49TDE",
        "49TEE",
        "49TFE",
        "49TGE",
        "50TMT",
        "50TNT",
        "50TPT",
        "50TQT",
        "50TMS",
        "50TNS",
        "50TPS",
        "50TQS",
        "50TLR",
        "50TMR",
        "50TNR",
        "50TPR",
        "50TQR",
        "50TLQ",
        "50TMQ",
        "50TNQ",
        "50TPQ",
        "50TQQ",
        "50TLP",
        "50TMP",
        "50TNP",
        "50TPP",
        "50TQP",
        "50TLN",
        "50TMN",
        "50TNN",
        "50TPN",
        "50TQN",
        "50TLM",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TQM",
        "50TKL",
        "50TPL",
        "50TQL",
        "50TKK",
        "50UQC",
        "50UPB",
        "50UQB",
        "50UMA",
        "50UNA",
        "50UPA",
        "50UQA",
        "50UMV",
        "50UNV",
        "50UPV",
        "50UQV",
        "50ULU",
        "50UMU",
        "50UNU",
        "50UPU",
        "50UQU",
        "51TUN",
        "51TVN",
        "51TWN",
        "51TUM",
        "51TVM",
        "51TWM",
        "51TUL",
        "51TVL",
        "51TUK",
        "51TVK",
        "51TWK",
        "51TUJ",
        "51TVJ",
        "51TWJ",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TUG",
        "51UUV",
        "51UVV",
        "51UUU",
        "51UVU",
        "51UUT",
        "51UVT",
        "51UXT",
        "51UUS",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UUR",
        "51UVR",
        "51UWR",
        "51UXR",
        "51UUQ",
        "51UVQ",
        "51UWQ",
        "51UXQ",
        "51UUP",
        "51UVP",
        "51UWP",
        "51UXP",
        "47SND",
        "47SPD",
        "47SQD",
        "47SPC",
        "47SQC",
        "47TLH",
        "47TMH",
        "47TNH",
        "47TPH",
        "47TQH",
        "47TLG",
        "47TMG",
        "47TNG",
        "47TPG",
        "47TQG",
        "47TLF",
        "47TMF",
        "47TNF",
        "47TPF",
        "47TQF",
        "47TNE",
        "47TPE",
        "47TQE",
        "48TTM",
        "49TBG",
        "50TKM",
        "51TTG"
    ],
    "辽宁省": [
        "50TPM",
        "50TQM",
        "50TPL",
        "50TQL",
        "50TPK",
        "50TQK",
        "51SUD",
        "51SVD",
        "51SWD",
        "51SUC",
        "51TWJ",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TXH",
        "51TUG",
        "51TVG",
        "51TWG",
        "51TXG",
        "51TYG",
        "51TTF",
        "51TUF",
        "51TVF",
        "51TWF",
        "51TXF",
        "51TYF",
        "51TTE",
        "51TUE",
        "51TVE",
        "51TWE",
        "51TXE",
        "51TYE",
        "51TTG"
    ],
    "江西省": [
        "49RGN",
        "49RGM",
        "49RGL",
        "49RGK",
        "49RGJ",
        "49RHJ",
        "50RLU",
        "50RMU",
        "50RNU",
        "50RKT",
        "50RLT",
        "50RMT",
        "50RNT",
        "50RPT",
        "50RKS",
        "50RLS",
        "50RMS",
        "50RNS",
        "50RPS",
        "50RKR",
        "50RLR",
        "50RMR",
        "50RNR",
        "50RPR",
        "50RKQ",
        "50RLQ",
        "50RMQ",
        "50RNQ",
        "50RKP",
        "50RLP",
        "50RMP",
        "50RKN",
        "50RLN"
    ],
    "吉林省": [
        "51TVM",
        "51TWM",
        "51TUL",
        "51TVL",
        "51TWL",
        "51TXL",
        "51TYL",
        "51TVK",
        "51TWK",
        "51TXK",
        "51TYK",
        "51TVJ",
        "51TWJ",
        "51TXJ",
        "51TYJ",
        "51TWH",
        "51TXH",
        "51TYH",
        "51TXG",
        "51TYG",
        "51TYF",
        "52TCR",
        "52TCQ",
        "52TDQ",
        "52TCP",
        "52TDP",
        "52TEP",
        "52TFP",
        "52TCN",
        "52TDN",
        "52TEN",
        "52TFN",
        "52TCM",
        "52TDM",
        "52TEM",
        "52TFM",
        "52TBL",
        "52TCL",
        "52TDL",
        "52TBM"
    ],
    "湖南省": [
        "49RDP",
        "49REP",
        "49RGP",
        "49RCN",
        "49RDN",
        "49REN",
        "49RFN",
        "49RGN",
        "49RCM",
        "49RDM",
        "49REM",
        "49RFM",
        "49RGM",
        "49RBL",
        "49RCL",
        "49RDL",
        "49REL",
        "49RFL",
        "49RGL",
        "49RBK",
        "49RCK",
        "49RDK",
        "49REK",
        "49RFK",
        "49RGK",
        "49RCJ",
        "49RDJ",
        "49REJ",
        "49RFJ",
        "49RGJ",
        "49RHJ",
        "49RDH",
        "49REH",
        "49RFH",
        "49RGH",
        "50RKT",
        "50RKS",
        "50RKQ",
        "50RKP"
    ],
    "湖北省": [
        "49RCQ",
        "49RDQ",
        "49REQ",
        "49RFQ",
        "49RGQ",
        "49RBP",
        "49RCP",
        "49RDP",
        "49REP",
        "49RFP",
        "49RGP",
        "49RBN",
        "49RCN",
        "49RDN",
        "49REN",
        "49RFN",
        "49RGN",
        "49SCS",
        "49SDS",
        "49SES",
        "49SCR",
        "49SDR",
        "49SER",
        "49SFR",
        "49SGR",
        "50RKV",
        "50RLV",
        "50RMV",
        "50RKU",
        "50RLU",
        "50RMU",
        "50RKT",
        "50RLT",
        "50RMT"
    ],
    "黑龙江": [
        "51TVN",
        "51TWN",
        "51TXN",
        "51TYN",
        "51TVM",
        "51TWM",
        "51TXM",
        "51TYM",
        "51TWL",
        "51TXL",
        "51TYL",
        "51UUV",
        "51UVV",
        "51UWV",
        "51UUU",
        "51UVU",
        "51UWU",
        "51UXU",
        "51UYU",
        "51UVT",
        "51UWT",
        "51UXT",
        "51UYT",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UXR",
        "51UYR",
        "51UXQ",
        "51UYQ",
        "51UWP",
        "51UXP",
        "51UYP",
        "52TCT",
        "52TDT",
        "52TET",
        "52TFT",
        "52TGT",
        "52TCS",
        "52TDS",
        "52TES",
        "52TFS",
        "52TGS",
        "52TCR",
        "52TDR",
        "52TER",
        "52TFR",
        "52TGR",
        "52TCQ",
        "52TDQ",
        "52TEQ",
        "52TFQ",
        "52TGQ",
        "52TCP",
        "52TDP",
        "52TEP",
        "52TFP",
        "52UCD",
        "52UCC",
        "52UCB",
        "52UCA",
        "52UDA",
        "52UCV",
        "52UDV",
        "52UEV",
        "52UFV",
        "52UCU",
        "52UDU",
        "52UEU",
        "52UFU",
        "53TLN",
        "53TMN",
        "53TLM",
        "53TMM",
        "53TLL",
        "53TML",
        "53TLK",
        "53ULP",
        "53UMP",
        "53UNP"
    ],
    "河南省": [
        "49SGA",
        "49SEV",
        "49SFV",
        "49SGV",
        "49SDU",
        "49SEU",
        "49SFU",
        "49SGU",
        "49SDT",
        "49SET",
        "49SFT",
        "49SGT",
        "49SDS",
        "49SES",
        "49SFS",
        "49SGS",
        "49SER",
        "49SFR",
        "49SGR",
        "50RKV",
        "50RLV",
        "50SKF",
        "50SLF",
        "50SKE",
        "50SLE",
        "50SME",
        "50SKD",
        "50SLD",
        "50SMD",
        "50SKC",
        "50SLC",
        "50SMC",
        "50SKB",
        "50SLB",
        "50SKA",
        "50SLA"
    ],
    "北京市": [
        "50SLJ",
        "50SMJ",
        "50TML",
        "50TNL",
        "50TLK",
        "50TMK",
        "50TNK"
    ],
    "天津市": [
        "50SMJ",
        "50SNJ",
        "50SMH",
        "50SNH",
        "50TNK"
    ],
    "海南省": [
        "49QCC",
        "49QDC",
        "49QBB",
        "49QCB",
        "49QDB",
        "49QEB",
        "49QBA",
        "49QCA",
        "49QDA"
    ],
    "贵州省": [
        "48RYT",
        "48RWS",
        "48RXS",
        "48RYS",
        "48RUR",
        "48RVR",
        "48RWR",
        "48RXR",
        "48RYR",
        "48RUQ",
        "48RVQ",
        "48RWQ",
        "48RXQ",
        "48RYQ",
        "48RVP",
        "48RWP",
        "48RXP",
        "48RYP",
        "48RZP",
        "48RVN",
        "48RWN",
        "48RXN",
        "48RYN",
        "48RZN",
        "49RBN",
        "49RBM",
        "49RCM",
        "49RBL",
        "49RCL",
        "49RBK",
        "49RCK",
        "49RBJ",
        "49RCJ",
        "49RBH"
    ],
    "广西省": [
        "48QWM",
        "48QXM",
        "48QYM",
        "48QZM",
        "48QWL",
        "48QXL",
        "48QYL",
        "48QZL",
        "48QXK",
        "48QYK",
        "48QZK",
        "48QYJ",
        "48QZJ",
        "48RXP",
        "48RYP",
        "48RVN",
        "48RWN",
        "48RXN",
        "48RYN",
        "48RZN",
        "49QBG",
        "49QCG",
        "49QDG",
        "49QEG",
        "49QBF",
        "49QCF",
        "49QDF",
        "49QEF",
        "49QBE",
        "49QCE",
        "49QDE",
        "49QBD",
        "49QCD",
        "49RDK",
        "49REK",
        "49RBJ",
        "49RCJ",
        "49RDJ",
        "49REJ",
        "49RBH",
        "49RCH",
        "49RDH",
        "49REH",
        "49RFH"
    ],
    "甘肃省": [
        "48STJ",
        "48SUJ",
        "48SVJ",
        "48STH",
        "48SUH",
        "48SVH",
        "48STG",
        "48SUG",
        "48SVG",
        "48SXG",
        "48SYG",
        "48STF",
        "48SUF",
        "48SVF",
        "48SWF",
        "48SXF",
        "48SYF",
        "48STE",
        "48SUE",
        "48SVE",
        "48SWE",
        "48SXE",
        "48SYE",
        "48STD",
        "48SUD",
        "48SVD",
        "48SWD",
        "48SXD",
        "48SYD",
        "48STC",
        "48SUC",
        "48SVC",
        "48SWC",
        "48SXC",
        "48STB",
        "48SVB",
        "48SWB",
        "49SBA",
        "49SBV",
        "46SDJ",
        "46SEJ",
        "46SFJ",
        "46SGJ",
        "46SGH",
        "46TFM",
        "46TGM",
        "46TEL",
        "46TFL",
        "46TGL",
        "46TDK",
        "46TEK",
        "46TFK",
        "46TGK",
        "47SKD",
        "47SLD",
        "47SMD",
        "47SND",
        "47SPD",
        "47SQD",
        "47SKC",
        "47SLC",
        "47SMC",
        "47SNC",
        "47SPC",
        "47SQC",
        "47SPB",
        "47SQB",
        "47SPU",
        "47SQU",
        "47SPT",
        "47SQT",
        "47SQS",
        "47TLH",
        "47TLG",
        "47TMG",
        "47TKF",
        "47TLF",
        "47TMF",
        "47TNF",
        "47TPF",
        "47TKE",
        "47TLE",
        "47TME",
        "47TNE",
        "47TPE",
        "47TKG"
    ],
    "福建省": [
        "50QMM",
        "50QNM",
        "50RPS",
        "50RMR",
        "50RNR",
        "50RPR",
        "50RQR",
        "50RMQ",
        "50RNQ",
        "50RPQ",
        "50RQQ",
        "50RLP",
        "50RMP",
        "50RNP",
        "50RPP",
        "50RQP",
        "50RLN",
        "50RMN",
        "50RNN",
        "50RPN",
        "50RQN",
        "51RTL",
        "51RTK"
    ],
    "澳门": [
        "49QGE"
    ],
    "安徽省": [
        "50RLV",
        "50RMV",
        "50RNV",
        "50RPV",
        "50RQV",
        "50RLU",
        "50RMU",
        "50RNU",
        "50RPU",
        "50RQU",
        "50RMT",
        "50RNT",
        "50RPT",
        "50SMD",
        "50SLC",
        "50SMC",
        "50SNC",
        "50SPC",
        "50SLB",
        "50SMB",
        "50SNB",
        "50SPB",
        "50SQB",
        "50SLA",
        "50SMA",
        "50SNA",
        "50SPA",
        "50SQA"
    ],
    "上海市": [
        "51RTQ",
        "51RUQ",
        "51RVQ",
        "51RUP"
    ],
    "重庆市": [
        "48RYV",
        "48RWU",
        "48RXU",
        "48RYU",
        "48RWT",
        "48RXT",
        "48RYT",
        "48RWS",
        "48RXS",
        "48RYS",
        "49RBQ",
        "49RCQ",
        "49RDQ",
        "49RBP",
        "49RCP",
        "49RBN",
        "49RCN",
        "49RBM",
        "49RCM",
        "49SBR"
    ],
    "江苏省": [
        "50RPV",
        "50RQV",
        "50SMD",
        "50SND",
        "50SPD",
        "50SQD",
        "50SMC",
        "50SNC",
        "50SPC",
        "50SQC",
        "50SNB",
        "50SPB",
        "50SQB",
        "50SPA",
        "50SQA",
        "51RTQ",
        "51RUQ",
        "51STU",
        "51STT",
        "51STS",
        "51SUS",
        "51STR",
        "51SUR"
    ],
    "广东省": [
        "49QEG",
        "49QFG",
        "49QGG",
        "49QHG",
        "49QDF",
        "49QEF",
        "49QFF",
        "49QGF",
        "49QHF",
        "49QCE",
        "49QDE",
        "49QEE",
        "49QFE",
        "49QGE",
        "49QHE",
        "49QCD",
        "49QDD",
        "49QED",
        "49QCC",
        "49QDC",
        "49RFJ",
        "49RGJ",
        "49RHJ",
        "49REH",
        "49RFH",
        "49RGH",
        "49RHH",
        "50QKM",
        "50QLM",
        "50QMM",
        "50QNM",
        "50QKL",
        "50QLL",
        "50QML",
        "50QKK",
        "50RKP",
        "50RKN",
        "50RLN",
        "50RMN"
    ],
    "河北省": [
        "49SGD",
        "49SGC",
        "49SGB",
        "49SGA",
        "49TGG",
        "49TGF",
        "49TGE",
        "50SKJ",
        "50SLJ",
        "50SMJ",
        "50SNJ",
        "50SPJ",
        "50SQJ",
        "50SKH",
        "50SLH",
        "50SMH",
        "50SNH",
        "50SKG",
        "50SLG",
        "50SMG",
        "50SNG",
        "50SKF",
        "50SLF",
        "50SLE",
        "50TNN",
        "50TLM",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TKL",
        "50TLL",
        "50TML",
        "50TNL",
        "50TPL",
        "50TKK",
        "50TLK",
        "50TMK",
        "50TNK",
        "50TPK",
        "50TQK",
        "50TKM"
    ],
    "东四盟": [
        "50TLU",
        "50TMU",
        "50TNU",
        "50TPU",
        "50TQU",
        "50TMT",
        "50TNT",
        "50TPT",
        "50TQT",
        "50TQS",
        "50TPR",
        "50TQR",
        "50TPQ",
        "50TQQ",
        "50TMP",
        "50TNP",
        "50TPP",
        "50TQP",
        "50TMN",
        "50TNN",
        "50TPN",
        "50TQN",
        "50TMM",
        "50TNM",
        "50TPM",
        "50TQM",
        "50TPL",
        "50TQL",
        "50UQC",
        "50UPB",
        "50UQB",
        "50UMA",
        "50UNA",
        "50UPA",
        "50UQA",
        "50UMV",
        "50UNV",
        "50UPV",
        "50UQV",
        "50ULU",
        "50UMU",
        "50UNU",
        "50UPU",
        "50UQU",
        "51TTP",
        "51TUP",
        "51TVP",
        "51TWP",
        "51TTN",
        "51TUN",
        "51TVN",
        "51TWN",
        "51TTM",
        "51TUM",
        "51TVM",
        "51TWM",
        "51TTL",
        "51TUL",
        "51TVL",
        "51TTK",
        "51TUK",
        "51TVK",
        "51TWK",
        "51TTJ",
        "51TUJ",
        "51TVJ",
        "51TWJ",
        "51TTH",
        "51TUH",
        "51TVH",
        "51TWH",
        "51TTG",
        "51TUG",
        "51UUV",
        "51UVV",
        "51UTU",
        "51UUU",
        "51UVU",
        "51UTT",
        "51UUT",
        "51UVT",
        "51UXT",
        "51UTS",
        "51UUS",
        "51UVS",
        "51UWS",
        "51UXS",
        "51UYS",
        "51UTR",
        "51UUR",
        "51UVR",
        "51UWR",
        "51UXR",
        "51UTQ",
        "51UUQ",
        "51UVQ",
        "51UWQ",
        "51UXQ",
        "51UTP",
        "51UUP",
        "51UVP",
        "51UWP",
        "51UXP",
        "52UBB"
    ]
}


# os.system(r"net use Z: \\192.168.2.172\root DELL123dell /user:root /PERSISTENT:YES")


class PepsDownload:
    def __init__(
        self, 
        username="fengzhipo@outlook.com",
        password="3edc@WSX",
        location=None,
        auth=None,
        write_dir='.',
        collection='S2ST',
        product_type="",
        sensor_mode="",
        no_download=False,
        start_date=None,
        tile=None,
        lat=None,
        lon=None,
        latmin=None,
        latmax=None,
        lonmin=None,
        lonmax=None,
        orbit=None,
        end_date='9999-01-01',
        search_json_file=None,
        windows=True,
        clouds=100,
        sat=None,
        extract=None):
        """
        利用PEPS下载哨兵数据
        :param location: town name (pick one which is not too frequent to avoid confusions)
        :param auth: Peps account and password file
        :param write_dir: Path where the products should be downloaded
        :param collection: Collection within theia collections", choices=['S1', 'S2', 'S2ST', 'S3']
        :param product_type: GRD, SLC, OCN (for S1) | S2MSI1C S2MSI2A S2MSI2Ap (for S2)
        :param sensor_mode: EW, IW , SM, WV (for S1) | INS-NOBS, INS-RAW (for S3)
        :param no_download: Do not download products, just print curl command
        :param start_date: start date, fmt('2015-12-22')
        :param tile: Sentinel-2 tile number
        :param lat: latitude in decimal degrees
        :param lon: longitude in decimal degrees
        :param latmin: min latitude in decimal degrees
        :param latmax: max latitude in decimal degrees
        :param lonmin: min longitude in decimal degrees
        :param lonmax: max longitude in decimal degrees
        :param orbit: Orbit Path number
        :param end_date: end date, fmt('2015-12-23')
        :param search_json_file: Output search JSON filename
        :param windows: For windows usage
        :param clouds: Maximum cloud coverage
        :param sat: S1A,S1B,S2A,S2B,S3A,S3B
        :param extract: Extract and remove zip file after download
        """
        # 设置下载参数
        self.username = username
        self.password = password
        self.location = location
        self.auth = auth
        self.write_dir = write_dir
        self.collection = collection
        self.product_type = product_type
        self.sensor_mode = sensor_mode
        self.no_download = no_download
        self.start_date = start_date
        self.tile = tile
        self.lat = lat
        self.lon = lon
        self.latmin = latmin
        self.latmax = latmax
        self.lonmin = lonmin
        self.lonmax = lonmax
        self.orbit = orbit
        self.end_date = end_date
        self.search_json_file = search_json_file
        self.windows = windows
        self.clouds = clouds
        self.sat = sat
        self.extract = extract
        # 下载文件
        self.downloader()

    ###########################################################################
    def check_rename(self, tmpfile, prodsize, prod):
        print(os.path.getsize(tmpfile), prodsize)
        if os.path.getsize(tmpfile) != prodsize:
            with open(tmpfile) as f_tmp:
                try:
                    tmp_data = json.load(f_tmp)
                    print("Result is a json file (might come from a wrong password file)")
                    print(tmp_data)
                    sys.exit(-1)
                except ValueError:
                    print("\ndownload was not complete, tmp file removed")
                    os.remove(tmpfile)
                    return

        zfile = "%s/%s.zip" % (self.write_dir, prod)
        # os.system('mv -f %s %s ' % (tmpfile, zfile))
        os.rename(tmpfile, zfile)
        # Unzip file
        if self.extract and os.path.exists(zfile):
            try:
                with zipfile.ZipFile(zfile, 'r') as zf:
                    safename = zf.namelist()[0].replace('/', '')
                    zf.extractall(self.write_dir)
                safedir = os.path.join(self.write_dir, safename)
                if not os.path.isdir(safedir):
                    raise Exception('Unzipped directory not found: ', zfile)

            except Exception as e:
                print(e)
                print('Could not unzip file: ' + zfile)
                os.remove(zfile)
                print('Zip file removed.')
                return

            else:
                print('product saved as : ' + safedir)
                os.remove(zfile)
                return

        print("product saved as : " + zfile)

    def parse_catalog(self):
        # Filter catalog result
        with open(self.search_json_file) as data_file:
            data = json.load(data_file)

        if 'ErrorCode' in data:
            print(data['ErrorMessage'])
            sys.exit(-2)

        # Sort data
        download_dict = {}
        storage_dict = {}
        size_dict = {}
        if len(data["features"]) > 0:
            for i in range(len(data["features"])):
                prod = data["features"][i]["properties"]["productIdentifier"]
                # print(prod, data["features"][i]["properties"]["storage"]["mode"])
                feature_id = data["features"][i]["id"]
                try:
                    storage = data["features"][i]["properties"]["storage"]["mode"]
                    platform = data["features"][i]["properties"]["platform"]
                    resourceSize = int(data["features"][i]["properties"]["resourceSize"])
                    if storage == "unknown":
                        print('found a product with "unknown" status : %s' % prod)
                        print("product %s cannot be downloaded" % prod)
                        print('please send and email with product name to peps admin team : exppeps@cnes.fr')
                    else:
                        # recup du numero d'orbite
                        orbitN = data["features"][i]["properties"]["orbitNumber"]
                        if platform == 'S1A':
                            # calcul de l'orbite relative pour Sentinel 1A
                            relativeOrbit = ((orbitN - 73) % 175) + 1
                        elif platform == 'S1B':
                            # calcul de l'orbite relative pour Sentinel 1B
                            relativeOrbit = ((orbitN - 27) % 175) + 1

                        if self.orbit is not None:
                            if platform.startswith('S2'):
                                if prod.find("_R%03d" % self.orbit) > 0:
                                    download_dict[prod] = feature_id
                                    storage_dict[prod] = storage
                                    size_dict[prod] = resourceSize

                            elif platform.startswith('S1'):
                                if relativeOrbit == self.orbit:
                                    download_dict[prod] = feature_id
                                    storage_dict[prod] = storage
                                    size_dict[prod] = resourceSize
                        else:
                            download_dict[prod] = feature_id
                            storage_dict[prod] = storage
                            size_dict[prod] = resourceSize

                except:
                    pass

            # cloud cover criterium:
            if self.collection[0:2] == 'S2':
                for i in range(len(data["features"])):
                    prod = data["features"][i]["properties"]["productIdentifier"]
                    if data["features"][i]["properties"]["cloudCover"] > self.clouds:
                        del download_dict[prod], storage_dict[prod], size_dict[prod]

            # selecion of specific satellite
            if self.sat is not None:
                for i in range(len(data["features"])):
                    prod = data["features"][i]["properties"]["productIdentifier"]
                    if data["features"][i]["properties"]["platform"] != self.sat:
                        try:
                            del download_dict[prod], storage_dict[prod], size_dict[prod]
                        except KeyError:
                            pass

            for prod in download_dict.keys():
                print(prod, storage_dict[prod])
        else:
            print(">>> no product corresponds to selection criteria")
            sys.exit(-1)
        #    print(download_dict.keys())

        return (prod, download_dict, storage_dict, size_dict)

    # sentinel data download function
    def downloader(self):
        if self.search_json_file is None or self.search_json_file == "":
            self.search_json_file = 'search.json'

        if self.sat is not None:
            print(self.sat, self.collection[0:2])
            if not self.sat.startswith(self.collection[0:2]):
                print("input parameters collection and satellite are incompatible")
                sys.exit(-1)

        if self.tile is None:
            if self.location is None:
                if self.lat is None or self.lon is None:
                    if (self.latmin is None) or (self.lonmin is None) or (self.latmax is None) or (
                            self.lonmax is None):
                        print("provide at least a point or rectangle or tile number")
                        sys.exit(-1)
                    else:
                        geom = 'rectangle'
                else:
                    if (self.latmin is None) and (self.lonmin is None) and (self.latmax is None) and (
                            self.lonmax is None):
                        geom = 'point'
                    else:
                        print("please choose between point and rectangle, but not both")
                        sys.exit(-1)
            else:
                if (self.latmin is None) and (self.lonmin is None) and (self.latmax is None) and (
                        self.lonmax is None) and (self.lat is None) or (self.lon is None):
                    geom = 'location'
                else:
                    print("please choose location and coordinates, but not both")
                    sys.exit(-1)

        # geometric parameters of catalog request

        if self.tile is not None:
            if self.tile.startswith('T') and len(self.tile) == 6:
                tileid = self.tile[1:6]
            elif len(self.tile) == 5:
                tileid = self.tile[0:5]
            else:
                print("tile name is ill-formated : 31TCJ or T31TCJ are allowed")
                sys.exit(-4)
            query_geom = "tileid=%s" % (tileid)
        elif geom == 'point':
            query_geom = 'lat=%f\&lon=%f' % (self.lat, self.lon)
        elif geom == 'rectangle':
            query_geom = 'box={lonmin},{latmin},{lonmax},{latmax}'.format(
                latmin=self.latmin, latmax=self.latmax, lonmin=self.lonmin, lonmax=self.lonmax)
        elif geom == 'location':
            query_geom = "q=%s" % self.location

        # date parameters of catalog request
        if self.start_date is not None:
            start_date = self.start_date
            if self.end_date is not None:
                end_date = self.end_date
            else:
                end_date = datetime.date.today().isoformat()

        # special case for Sentinel-2

        if self.collection == 'S2':
            if self.start_date >= '2016-12-05':
                print("**** products after '2016-12-05' are stored in Tiled products collection")
                print("**** please use option -c S2ST")
            elif self.end_date >= '2016-12-05':
                print("**** products after '2016-12-05' are stored in Tiled products collection")
                print("**** please use option -c S2ST to get the products after that date")
                print("**** products before that date will be downloaded")

        if self.collection == 'S2ST':
            if self.end_date < '2016-12-05':
                print("**** products before '2016-12-05' are stored in non-tiled products collection")
                print("**** please use option -c S2")
            elif self.start_date < '2016-12-05':
                print("**** products before '2016-12-05' are stored in non-tiled products collection")
                print("**** please use option -c S2 to get the products before that date")
                print("**** products after that date will be downloaded")

        # ====================
        # read authentification file
        # ====================
        try:
            # f = open(self.auth)
            # (email, passwd) = f.readline().split(' ')
            # if passwd.endswith('\n'):
            #     passwd = passwd[:-1]
            # f.close()
            # email = "fengzhipo@outlook.com"
            # passwd = "3edc@WSX"
            email = self.username
            passwd = self.password
        except:
            print("error with password file")
            sys.exit(-2)

        if os.path.exists(self.search_json_file):
            os.remove(self.search_json_file)

        # ====================
        # search in catalog
        # ====================
        if (self.product_type == "") and (self.sensor_mode == ""):
            search_catalog = 'curl -k -o %s https://peps.cnes.fr/resto/api/collections/%s/search.json?%s\&startDate=%s\&completionDate=%s\&maxRecords=500' % (
                self.search_json_file, self.collection, query_geom, start_date, end_date)
        else:
            search_catalog = 'curl -k -o %s https://peps.cnes.fr/resto/api/collections/%s/search.json?%s\&startDate=%s\&completionDate=%s\&maxRecords=500\&productType=%s\&sensorMode=%s' % (
                self.search_json_file, self.collection, query_geom, start_date, end_date, self.product_type,
                self.sensor_mode)

        if self.windows:
            search_catalog = search_catalog.replace('\&', '^&')

        print(search_catalog)
        os.system(search_catalog)
        time.sleep(5)

        prod, download_dict, storage_dict, size_dict = self.parse_catalog()

        # ====================
        # Download
        # ====================

        if len(download_dict) == 0:
            print("No product matches the criteria")
        else:
            # first try for the products on tape
            if self.write_dir is None:
                self.write_dir = os.getcwd()

            for prod in list(download_dict.keys()):
                file_exists = os.path.exists(("%s/%s.SAFE") % (self.write_dir, prod)
                                             ) or os.path.exists(("%s/%s.zip") % (self.write_dir, prod))
                if (not (self.no_download) and not (file_exists)):
                    if storage_dict[prod] == "tape":
                        tmticks = time.time()
                        tmpfile = ("%s/tmp_%s.tmp") % (self.write_dir, tmticks)
                        print("\nStage tape product: %s" % prod)
                        get_product = 'curl -o %s -k -u "%s:%s" https://peps.cnes.fr/resto/collections/%s/%s/download/?issuerId=peps &>/dev/null' % (
                            tmpfile, email, passwd, self.collection, download_dict[prod])
                        os.system(get_product)
                        if os.path.exists(tmpfile):
                            os.remove(tmpfile) 

            NbProdsToDownload = len(list(download_dict.keys()))
            print("##########################")
            print("%d  products to download" % NbProdsToDownload)
            print("##########################")
            while (NbProdsToDownload > 0):
                # redo catalog search to update disk/tape status
                if (self.product_type == "") and (self.sensor_mode == ""):
                    search_catalog = 'curl -k -o %s https://peps.cnes.fr/resto/api/collections/%s/search.json?%s\&startDate=%s\&completionDate=%s\&maxRecords=500' % (
                        self.search_json_file, self.collection, query_geom, start_date, end_date)
                else:
                    search_catalog = 'curl -k -o %s https://peps.cnes.fr/resto/api/collections/%s/search.json?%s\&startDate=%s\&completionDate=%s\&maxRecords=500\&productType=%s\&sensorMode=%s' % (
                        self.search_json_file, self.collection, query_geom, start_date, end_date,
                        self.product_type, self.sensor_mode)

                if self.windows:
                    search_catalog = search_catalog.replace('\&', '^&')

                os.system(search_catalog)
                time.sleep(2)

                prod, download_dict, storage_dict, size_dict = self.parse_catalog()

                NbProdsToDownload = 0
                # download all products on disk
                for prod in list(download_dict.keys()):
                    file_exists = os.path.exists(("%s/%s.SAFE") % (self.write_dir, prod)
                                                 ) or os.path.exists(("%s/%s.zip") % (self.write_dir, prod))
                    if (not (self.no_download) and not (file_exists)):
                        if storage_dict[prod] == "disk":
                            tmticks = time.time()
                            tmpfile = ("%s/tmp_%s.tmp") % (self.write_dir, tmticks)
                            print("\nDownload of product : %s" % prod)
                            get_product = 'curl -o %s -k -u "%s:%s" https://peps.cnes.fr/resto/collections/%s/%s/download/?issuerId=peps' % (
                                tmpfile, email, passwd, self.collection, download_dict[prod])
                            print(get_product)
                            os.system(get_product)
                            # check binary product, rename tmp file
                            if not os.path.exists(("%s/tmp_%s.tmp") % (self.write_dir, tmticks)):
                                NbProdsToDownload += 1
                            else:
                                self.check_rename(tmpfile, size_dict[prod], prod)

                    elif file_exists:
                        print("%s already exists" % prod)

                # download all products on tape
                for prod in list(download_dict.keys()):
                    file_exists = os.path.exists(("%s/%s.SAFE") % (self.write_dir, prod)
                                                 ) or os.path.exists(("%s/%s.zip") % (self.write_dir, prod))
                    if (not (self.no_download) and not (file_exists)):
                        if storage_dict[prod] == "tape" or storage_dict[prod] == "staging":
                            NbProdsToDownload += 1

                if NbProdsToDownload > 0:
                    print("##############################################################################")
                    print(f"{NbProdsToDownload} remaining products are on tape, lets's wait 1 minute before trying again")
                    print("##############################################################################")
                    time.sleep(60)


def peps_download(args):
    [username,password,tile,start_date,end_date,clouds,folder] = args
    json_name = f"{tile}_{start_date}_{end_date}_{clouds}.json"
    json_path = os.path.join(folder, json_name)
    PepsDownload(
        username=username,
        password=password,
        tile=tile,
        start_date=start_date,
        end_date=end_date,
        clouds=clouds,
        search_json_file=json_path,
        write_dir=folder)
    if os.path.exists(json_path):os.remove(json_path)
    return


def sentinel2_downloader(
    username,
    password,
    tiles,
    start_date,
    end_date,
    folder,
    threads=10,
    clouds=100):
    """sentinel2_downloader 
    peps下载工具
    :param str username: peps用户账户
    :param str password: peps用户密码
    :param list tiles: 图幅号列表
    :param str start_date: '2022-07-01', 
    :param str end_date: '2022-07-31'
    :param str folder: 文件下载路径
    :param int threads: 线程数量, defaults to 4
    :param int clouds: 含云量, defaults to 100
    """
    for index in tqdm(range(0,len(tiles),threads),desc="PEPS下载："):
        args_list = [
            [username,password,tile,start_date,end_date,clouds,folder]
            for tile in tiles[index : index + threads]]
        pool=ThreadPool(threads)
        pool.map(peps_download, args_list)
        pool.close;pool.join()
    return


if __name__ == "__main__":
    username="fengzhipo@outlook.com"
    password="3edc@WSX"
    tiles = china_tiles["河北省"]
    start_date = "2022-06-01"
    end_date = "2022-06-30"
    folder = r"E:\Image2"
    sentinel2_downloader(
        username,
        password,
        tiles,
        start_date,
        end_date,
        folder,
        threads=4,
        clouds=100)
    print(f"{datetime.datetime.now()}，End!")